from flask import (
    views,
    Blueprint,
    request
)
from network import (
    success_response,
    failure_response,
    req_data_error_response,
    parse_data,
)
from network.NetworkModel_pb2 import (
    FeedsCategory,
    FeedsEntityRequest,
    FeedsEntity,
    FeedItem
)
from feeds.models import (
    Feed
)
from utils import RedisOperation

bp = Blueprint('feeds', __name__, url_prefix='/feeds')


class CategoryView(views.MethodView):
    def get(self):
        feeds = Feed.query.order_by(Feed.id).all()
        category = FeedsCategory()
        for feed in feeds:
            item = category.categories.add()
            item.fid = str(feed.id)
            item.title = feed.title
        return success_response(category)


class FeedPageView(views.MethodView):
    def post(self):
        req = parse_data(FeedsEntityRequest(), request)
        if len(req.fid) == 0 or len(req.uid) == 0 or req.page < 0:
            return req_data_error_response()
        feed = Feed.query.filter_by(id=req.fid).first()
        if feed is None:
            return req_data_error_response()
        if req.page == 0:
            return self.fetch_latest_feeds(req.fid, req.uid)
        else:
            return self.load_feeds_next_page(req.fid, req.page, req.uid)

    def fetch_latest_feeds(self, fid, uid):
        fid_rdm = RedisOperation(db=fid)
        keys = fid_rdm.get_keys()
        items = list(map(lambda key: fid_rdm.get_data(key), keys))
        self.update_user_fid_dict(uid, fid, items)
        total_page_count = int(len(items) / 10)
        items = items[0:10]
        return self.response(fid, 0, total_page_count, items)

    def update_user_fid_dict(self, uid, fid, items):
        u_rdm = RedisOperation(db=0)
        fid_dict = u_rdm.get_data(uid)
        if fid_dict is None:
            fid_dict = {}
        fid_dict[fid] = items
        u_rdm.set_data(uid, fid_dict, 60*60)

    def load_feeds_next_page(self, fid, page, uid):
        u_rdm = RedisOperation(db=0)
        fid_dict = u_rdm.get_data(uid)
        if fid_dict is None or fid_dict[fid] is None:
            return failure_response('列表更新了，请回到顶部刷新下')
        items = fid_dict[fid]
        total_page_count = int(len(items) / 10)
        start = page * 10
        end = start + 10
        items = items[start:end]
        return self.response(fid, page, total_page_count, items)

    def response(self, fid, page, total_page_count, items):
        entity = FeedsEntity()
        entity.fid = fid
        entity.currentPageIndex = page
        entity.totalPageCount = total_page_count
        for data in items:
            item = FeedItem()
            item.ParseFromString(data)
            feed = entity.feeds.add()
            feed.snapshotUrl = item.snapshotUrl
            feed.avatarUrl = item.avatarUrl
            feed.name = item.name
            feed.roomTitle = item.roomTitle
            feed.ruid = item.ruid
            feed.fid = str(fid)
        return success_response(entity)


bp.add_url_rule('/category/', view_func=CategoryView.as_view('category_view'))
bp.add_url_rule('/page/', view_func=FeedPageView.as_view('feed_page_view'))
